 //-----------------------------------------------------------------------------
//
//Copyright(c) 2020, ThorsianWay Technologies Co, Ltd
//All rights reserved.
//
//IP Name       :   pixel_shader
//File Name     :   tex_enviroment.v
//Module name   :   tex_enviroment
//Full name     :   tex enviroment for pixel and texl blend
//
//Author        :   zha daolu
//Email         :   
//Data          :   2020/5/13
//Version       :   V1.00
//
//Abstract      :   
//                  
//Called  by    :   GPU
//
//Modification history
//-----------------------------------------------------
//1.00: intial version 
//
//-----------------------------------------------------------------------------   

module tex_enviroment(
input clk,
input rst_n,
input [2:0] tex_env,
input [2:0] combine_rgb,
input [2:0] combine_alpha,
input [1:0] rgb_arg0,
input [1:0] rgb_arg1,
input [1:0] rgb_arg2,
input [1:0] alpha_arg0,
input [1:0] alpha_arg1,
input [1:0] alpha_arg2,
input [31:0] env_color,
input [31:0] x_in,
input [31:0] y_in,
input [31:0] z_in,
input [31:0] fog_x_in,
input [31:0] fog_y_in,
input [31:0] fog_z_in,
input [7:0] r_in,
input [7:0] g_in,
input [7:0] b_in,
input [7:0] a_in,
input [7:0] r_tex_in,
input [7:0] g_tex_in,
input [7:0] b_tex_in,
input [7:0] a_tex_in,
input fragment_in_valid,
output reg [31:0] x_out,
output reg [31:0] y_out,
output reg [31:0] z_out,
output reg [31:0] fog_x_out,
output reg [31:0] fog_y_out,
output reg [31:0] fog_z_out,
output reg [7:0] r_out,
output reg [7:0] g_out,
output reg [7:0] b_out,
output reg [7:0] a_out,
output reg fragment_out_valid

);

localparam REPLACE  = 0;
localparam MODULATE = 1;
localparam DECAL    = 2;
localparam BLEND    = 3;
localparam ADD      = 4;
localparam COMBINE  = 5;

localparam RGB_REPLACE                  = 0;
localparam RGB_MODULATE                 = 1;
localparam RGB_ADD                      = 2;
localparam RGB_ADD_SIGNED       = 3;
localparam RGB_INTERPOLATE      = 4;
localparam RGB_SUBTRACT                 = 5;
localparam RGB_RGB_DOT3                 = 6;
localparam RGB_RGBA_DOT3                = 7;

localparam ALPHA_REPLACE                = 0;
localparam ALPHA_MODULATE               = 1;
localparam ALPHA_ADD                    = 2;
localparam ALPHA_ADD_SIGNED     = 3;
localparam ALPHA_INTERPOLATE    = 4;
localparam ALPHA_SUBTRACT               = 5;

wire [15:0] r_in_x_r_tex = r_in * r_tex_in;
wire [15:0] g_in_x_g_tex = g_in * g_tex_in;
wire [15:0] b_in_x_b_tex = b_in * b_tex_in;
wire [15:0] a_in_x_a_tex = a_in * a_tex_in;


wire [15:0] r_in_x_1_minus_a_tex = r_in * (8'hff - a_tex_in);
wire [15:0] g_in_x_1_minus_a_tex = g_in * (8'hff - a_tex_in);
wire [15:0] b_in_x_1_minus_a_tex = b_in * (8'hff - a_tex_in);

wire [15:0] r_tex_x_a_tex = r_tex_in * (a_tex_in);
wire [15:0] g_tex_x_a_tex = g_tex_in * (a_tex_in);
wire [15:0] b_tex_x_a_tex = b_tex_in * (a_tex_in);

wire [15:0] r_in_x_1_minus_a_tex_plus_r_tex_x_a_tex = r_in_x_1_minus_a_tex + r_tex_x_a_tex;
wire [15:0] g_in_x_1_minus_a_tex_plus_g_tex_x_a_tex = g_in_x_1_minus_a_tex + g_tex_x_a_tex;
wire [15:0] b_in_x_1_minus_a_tex_plus_b_tex_x_a_tex = b_in_x_1_minus_a_tex + b_tex_x_a_tex;

wire [15:0] r_in_x_1_minus_r_tex = r_in * (8'hff - r_tex_in);
wire [15:0] g_in_x_1_minus_g_tex = g_in * (8'hff - g_tex_in);
wire [15:0] b_in_x_1_minus_b_tex = b_in * (8'hff - b_tex_in);

wire [15:0] r_c_x_r_tex = env_color[23:16] * (r_tex_in);
wire [15:0] g_c_x_g_tex = env_color[15:8]  * (g_tex_in);
wire [15:0] b_c_x_b_tex = env_color[7:0]   * (b_tex_in);

wire [15:0] r_in_x_1_minus_r_tex_plus_r_c_x_r_tex = r_in_x_1_minus_r_tex + r_c_x_r_tex;
wire [15:0] g_in_x_1_minus_g_tex_plus_g_c_x_g_tex = g_in_x_1_minus_g_tex + g_c_x_g_tex;
wire [15:0] b_in_x_1_minus_b_tex_plus_b_c_x_b_tex = b_in_x_1_minus_b_tex + b_c_x_b_tex;

wire [15:0] r_in_plus_r_tex = r_in + r_tex_in;
wire [15:0] g_in_plus_g_tex = g_in + g_tex_in;
wire [15:0] b_in_plus_b_tex = b_in + b_tex_in;




always@(posedge clk or negedge rst_n)
begin
        if(~rst_n)
        begin
                x_out      <= 32'b0;
                y_out      <= 32'b0;
                z_out      <= 32'b0;
                fog_x_out  <= 32'b0;
                fog_y_out  <= 32'b0;
                fog_z_out  <= 32'b0;
                fragment_out_valid <= 1'b0;
        end
        else
        begin
                x_out      <= x_in    ;
                y_out      <= y_in    ;
                z_out      <= z_in    ;
                fog_x_out  <= fog_x_in;
                fog_y_out  <= fog_y_in;
                fog_z_out  <= fog_z_in; 
                fragment_out_valid <= fragment_in_valid;
        end
end


always@(posedge clk or negedge rst_n)
begin
        if(~rst_n)
        begin
                r_out  <= 32'b0;
                g_out  <= 32'b0;
                b_out  <= 32'b0;
                a_out  <= 32'b0;
        end
        else
        begin
                case(tex_env)                   
                        REPLACE :
                                begin
                                        r_out  <= r_tex_in;
                                        g_out  <= g_tex_in;
                                        b_out  <= b_tex_in;
                                        a_out  <= a_tex_in;
                                end                     
                        MODULATE:
                                begin
                                        r_out  <= r_in_x_r_tex[15:8];
                                        g_out  <= g_in_x_g_tex[15:8];
                                        b_out  <= b_in_x_b_tex[15:8];
                                        a_out  <= a_in_x_a_tex[15:8];
                                end                             
                        DECAL   :
                                begin
                                        r_out  <= r_in_x_1_minus_a_tex_plus_r_tex_x_a_tex[15:8];
                                        g_out  <= g_in_x_1_minus_a_tex_plus_g_tex_x_a_tex[15:8];
                                        b_out  <= b_in_x_1_minus_a_tex_plus_b_tex_x_a_tex[15:8];
                                        a_out  <= a_in;
                                end                             
                        BLEND   :
                                begin
                                        r_out  <= r_in_x_1_minus_r_tex_plus_r_c_x_r_tex[15:8];
                                        g_out  <= g_in_x_1_minus_g_tex_plus_g_c_x_g_tex[15:8];
                                        b_out  <= b_in_x_1_minus_b_tex_plus_b_c_x_b_tex[15:8];
                                        a_out  <= a_in_x_a_tex[15:8];
                                end                             
                        ADD     :
                                begin
                                        r_out  <= r_in_plus_r_tex[15:8];
                                        g_out  <= g_in_plus_g_tex[15:8];
                                        b_out  <= b_in_plus_b_tex[15:8];
                                        a_out  <= a_in_x_a_tex[15:8];
                                end                             
                        /*COMBINE :
                                begin
                                        r_out  <= ;
                                        g_out  <= ;
                                        b_out  <= ;
                                        a_out  <= ;                             
                                end*/
                        default :
                                begin
                                        r_out  <= 32'b0;
                                        g_out  <= 32'b0;
                                        b_out  <= 32'b0;
                                        a_out  <= 32'b0;
                                end                             
                endcase
        end
end
/*
combine_rgba combine_rgba_uut(
.combine_rgb(combine_rgb),
.rgb_src0   (rgb_src0   ),
.rgb_src1       (rgb_src1       ),
.rgb_src2       (rgb_src2       ),
.rgb_op0        (rgb_op0        ),
.rgb_op1        (rgb_op1        ),
.rgb_op2        (rgb_op2        ),
.r_in           (r_in           ),
.g_in           (g_in           ),
.b_in           (b_in           ),
.a_in           (a_in           ),
.r_tex_in       (r_tex_in       ),
.g_tex_in       (g_tex_in       ),
.b_tex_in       (b_tex_in       ),
.a_tex_in       (a_tex_in       ),
.env_color  (env_color  ),
.red        (red        ),
.green      (green      ),
.blue       (blue       ),
.alpha      (alpha      )
);*/
endmodule
